
/**
 * nobittercontrol.h
 * 
 * NobitterControl controls the entire application
 * 
 * Copyright (c) 2008 Harunobu Oyama <nobukichi at gmail.com>
 * Licensed under GNU GPL version 3
 *
 */

#ifndef		NOBITTER_CONTROL_INCLUDED
#define		NOBITTER_CONTROL_INCLUDED

#include	<map>
#include	<QDateTime>
#include	<QObject>
#include	<QHttp>
#include	<QTimer>
#include	<QNetworkProxy>
#include	"filter.h"
#include	"tweet.h"

class NobitterCipher;
class NobitterModel;
class TwitterAPI;

class NobitterControl : public QObject
{
	Q_OBJECT
public:
	explicit NobitterControl(QObject * parent = 0);

	//! the model, which this controller is managing
	NobitterModel* model();

public:
	//! return the labels of who filters
	QStringList getWhoFilterLabels() const;

	//! return the labels of @ filters
	QStringList getAtFilterLabels() const;

	//! return the labels of when filters
	QStringList getWhenFilterLabels() const;

	//! return the name of my friends
	//! friends are group members + users appeared on my time line
	QStringList getFriendNames() const;

public slots:
	//! slot to start nobitter
	void slotStart();

	//! set user's twitter account name
	void slotSetUserName(const QString& userName);

	//! set group's gateway name
	void slotSetGroupGatewayName(const QString& gatewayName);

	//! send my tweet to Twitter server
	void slotSendMyTweet(const QString& myTweet);

	//! show option settings dialog
	void slotShowSettingsDialog();

	//! tell TwitterAPI to update user's time line
	//! TwitterAPI will return tweets to slotFeedTweets
	void slotUpdateMyTimeline();

	//! change the who filter to index-th one
	void slotChangeWhoFilter(int index);

	//! change the @ filter to index-th one
	void slotChangeAtFilter(int index);

	//! change the when filter to index-th one
	void slotChangeWhenFilter(int index);

	//! save to the model to the log file
	bool slotSave();
	
signals:
	//! emitted when request to Twitter server is sent
	void signalRequestStarted();

	//! emitted when all ongoing Twitter API requests complete
	void signalRequestDone();

	//! emitted when the status is upated
	void signalStatusUpdated(QString newStatus);
	
private slots:
	//! the slot to receive member list from TwitterAPI
	void slotSetGroupMemberList(int requestId, const QStringList& memberList);
	
	//! the slot to receive tweets from TwitterAPI
	void slotFeedTweets(int requestId, const TweetVector& tweets);
	
	//! show Twitter API error message
	void slotReportTwitterError(QHttp::Error error);

	//! show TinyURL API error message
	void slotReportTinyUrlError(QHttp::Error error);

	//! send encrypted tweet to Twitter server
	void slotSendEncryptedTweet(const QString& text, const QString& encryptedUrl);

	//! feed decrypted tweet to the model
	void slotFeedDecryptedTweet(const QString& encryptedUrl, const QString& text);

	//! show authentication failure message
	void slotAlertAuthenticationFailure(int requestId);

	//! show group not found message
	void slotShowNoSuchGroupError(int requestId);

	//! emit signalRequestStarted
	void slotEmitSignalRequestStarted();

	//! emit signalRequestDone
	void slotEmitSignalRequestDone();

	//! load the log file to the model
	bool slotLoad();

	//! save the log and quit the application
	void slotQuit();

private:
	QNetworkProxy proxy;

	bool isModelInitialized; //! true if the model is fed with initial twit's
	QDateTime mostRecentDateTime; //! date and time of the most recent message in the model
	bool authenticationDone; //! true when user authentication succeeds
	QString userName; //! cache of UserSettings::get()->twitterUserName()
	QString groupName;  //! cache of UserSettings::get()->gatewayUserName()
	QStringList groupMemberList; //! list of all members in the group

	NobitterCipher* pCipher;
	NobitterModel* pModel;
	TwitterAPI* pTwitter;
	QTimer* pUpdateTimer;

	std::map<QString, Tweet> tinyUrlToTweetCache;
	
	//! my friends are:
	//! group members + those who appeared on my time line, including myself :)
	//! this information is used for @user completion
	std::set<QString> myFriends;

	//! these should be extracted to FilterManager or something BEGIN
	std::vector<FilterPtr> whoFilters;
	std::vector<FilterPtr> atFilters;
	std::vector<FilterPtr> whenFilters;
	void updateWhoFilter();
	void setupWhenFilter();
	//! these should be extracted to FilterManager or something END

	//! add a new friend to myFriends
	void addFriend(const QString& newFriend);
	
	//! remove a friend fro mmyFriends
	void removeFriend(const QString& oldFriend);

	//! update proxy based on what's set to UserSettings
	void updateProxy();

	void setupAutoUpdateTimer();
	void connectTwitterApiSignals();
	void connectNobitterCipherSignals();

	void getGroupMembersTimeline();

	//! save last month log to a log file and throw away logs before the first day of the last month
	void saveLastMonthLog();

	//! disallow copy or assignment
	NobitterControl(const NobitterControl&);
	NobitterControl& operator=(const NobitterControl&);
};

#endif	//	NOBITTER_CONTROL_INCLUDED

